﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml.Serialization;
using NetLib;

namespace FrameBuilderLib
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }
        
        //HTML site;
        public struct ResultSite
        {
            public string pathSite;
            public int rank;
            public List<int> listmark;
        }
        Work_Net Net;
        List<HTML> Sites = new List<HTML>();
        public List<ResultSite> ResultSites = new List<ResultSite>();
        private int Rank;

        List<int> work_memory = new List<int>();

        public HTML HTML_Deserialize(string path)
        {
            XmlSerializer XmlSer = new XmlSerializer(typeof(HTML));
            FileStream stream = new FileStream(path, FileMode.Open);
            HTML html = (HTML)XmlSer.Deserialize(stream);
            stream.Close();
            return html;
        }


        public void MLV(string netpath)
        {
            ResultSite rs;
            string path = Application.StartupPath+@"..\..\..\..\..\Сайты";
            DirectoryInfo dir = new DirectoryInfo(path);
            FileInfo[] files;
            files = dir.GetFiles("*.htmindex");
            for (int i = 0; i < files.Count(); i++)
            {
                Sites.Add(HTML_Deserialize(files[i].FullName));
            }

            Net = new Work_Net(netpath);

            List<CaseFrame> StartCSs = new List<CaseFrame>();
            StartCSs = Net.Get_CaseFrames_Start();
            
            for (int i = 0; i < Sites.Count; i++)
            {
                work_memory = new List<int>();
                Rank = 10 * StartCSs.Count();
                if (Finding_in_site(StartCSs, Sites[i]))
                {
                    rs=new ResultSite();
                    rs.listmark=new List<int>();
                    rs.listmark.AddRange(work_memory);
                    rs.pathSite=files[i].FullName.Remove(files[i].FullName.Count() - 5);
                    rs.rank = Rank;
                    ResultSites.Add(rs);
                }

                List<ResultSite> query = (from c in ResultSites
                                            orderby c.rank descending
                                            select c).ToList();
                ResultSites = query;

            }


            //string str;
            //work_memory = (from c in StartCSs select c.GeneralNode.id).ToList();
            //foreach (CaseFrame caseFrame in StartCSs)
            //{
            //    str = "";
            //    foreach (List<string> s in caseFrame.Words)
            //    {
            //        str += s[0] + " ";
            //    }
            //    ResultSites.Add(str);
            //    listmark.Add(work_memory);
            //}

            
            // здесь будет вывод результатов
            //MessageBox.Show(ResultSites.Count.ToString());

        }

        /// <summary>
        /// поиск в заданных вершин в сайте
        /// </summary>
        /// <param name="lcf"></param>
        /// <param name="site"></param>
        /// <returns></returns>
        private bool Finding_in_site(List<CaseFrame> lcf, HTML site)
        {
            bool res = true;
            CaseFrame cs=new CaseFrame();
            List<int> lcontext,lgener;
            int i=0;
            while (i < lcf.Count)
            {             
                res = site.Find(lcf[i].Words); // ищем сразу в тексте
                if (res)
                {
                    work_memory.Add(lcf[i].GeneralNode.id);

                }
                else
                {
                    Rank -= 10;
                    if (Settings.concrete_concederation) // в тексте нет, значит выводим через другие
                    {
                        res = Finding_Child_CaseFrame(lcf[i], site);
                        if (res)
                        {
                            Rank += 3;
                        }

                    }

                }
                i++;
            }
            i--;
            if (Rank < 0) Rank = 0;
            if (Settings.context_concederation)
            {
                lcontext = Net.FindContext(lcf[i].GeneralNode.id);
                foreach (int i1 in lcontext)
                {
                    cs = Net.Get_CaseFrame(i1);
                    if (site.Find(cs.Words))
                    {
                        Rank += 2;
                        work_memory.Add(cs.GeneralNode.id);
                    }
                }

            }

            if (Settings.concrete_concederation)
            {
                //ищем еще обобщения
                lgener = Net.FindGeneralization(lcf[i].GeneralNode.id);
                foreach (int i1 in lgener)
                {
                    cs = Net.Get_CaseFrame(i1);
                    if (site.Find(cs.Words))
                    {
                        Rank += 3;
                        work_memory.Add(cs.GeneralNode.id);
                    }
                }

            }
            return (Rank>0);
        }

        /// <summary>
        /// Вывод дочерних вершин
        /// </summary>
        /// <param name="cs"></param>
        /// <param name="site"></param>
        /// <returns></returns>
        private bool Finding_Child_CaseFrame(CaseFrame cs,HTML site)
        {
            bool res = false;
            // пытаемся вывести другими путями   
            List<Link> links_aso = new List<Link>();
            List<Link> links_apo = new List<Link>();
            List<CaseFrame> lcs = new List<CaseFrame>();
            CaseFrame mycs = new CaseFrame();
            int i;
                               
            links_aso=Net.Find_aso(cs.GeneralNode.id);
            links_apo = Net.Find_apo(cs.GeneralNode.id);
            if (links_aso.Count > 0)
            {
                // нужно сформировать множество на подачу
                    
                for (i = 0; i < links_aso.Count; i++)
                {                       
                    mycs=Net.Get_CaseFrame(links_aso[i].start_node.id);
                    lcs.Add(mycs);
                }
                res = Search(lcs, site, 1);
                    
            }
            else
            {
                if (links_apo.Count > 0)
                {
                    lcs.Clear();
                    for (i = 0; i < links_apo.Count; i++)
                    {
                        mycs = Net.Get_CaseFrame(links_apo[i].start_node.id);
                        lcs.Add(mycs);
                    }
                    i = Settings.precent*links_apo.Count/100;
                    res = Search(lcs, site,i); // надо указывать сколько apartof нужно для доказательства
                }
            }

            return res;
        }

        /// <summary>
        /// Ищет множество понятий в конкретном сайте с указание минимального количества совпадений
        /// </summary>
        /// <param name="inf"></param>
        /// <param name="site"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        private bool Search(List<CaseFrame> inf,HTML site,int k)
        {
            int i = 0, j = 0;
            int oldRank = Rank;
            while(i<inf.Count)
            {
                if (work_memory.IndexOf(inf[i].GeneralNode.id) == -1)
                {
                    if (site.Find(inf[i].Words)) //ищем сразу в тексте
                    {
                        j++;
                        work_memory.Add(inf[i].GeneralNode.id);
                        Rank+= 1;
                    }
                    else
                    {
                        Rank -= 1;
                        if (Finding_Child_CaseFrame(inf[i], site))
                        {
                            j++;
                        }
                    }                 
                }
                else j++;
                i++;
            }

            if (j < k) Rank -= j;
            return (j>=k);
        }
      

        private void button1_Click(object sender, EventArgs e)
        {
            
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
                            
            
        }
    }
}
